<?php
/**
 * Author: Traveler
 * Time  : 2021/9/5 20:54
 */

namespace sunshine\traits;


use app\ErrorCode;
use sunshine\basic\RestController;
use sunshine\basic\RestService;
use sunshine\exceptions\ApiException;
use think\exception\ValidateException;
use think\Response;

/**
 * Trait ControllerRestTrait
 *
 * @package sunshine\traits
 * @property RestService $service Service实例
 * @mixin RestController
 */
trait ControllerRestTrait
{
    /**
     * 获取数据列表
     *
     * @return Response
     */
    public function select(): Response
    {
        $params = $this->request->get();
        $data   = $this->service->select($params);

        return $this->json->api(ErrorCode::SUCCESS, $data);
    }

    /**
     * 获取单条数据
     *
     * @param int $id 查询id
     * @return Response
     */
    public function find(int $id): Response
    {
        $data = $this->service->find($id);

        if (!$data) {
            return $this->json->api(ErrorCode::DATA_NOT_FOUND);
        }

        return $this->json->api(ErrorCode::SUCCESS, $data);
    }

    /**
     * 创建数据
     *
     * @param string|null $validate 验证器名称
     * @return Response
     */
    public function create(?string $validate = null): Response
    {
        $data = $this->request->post();

        if ($validate) {
            try {
                $this->validate($data, $validate);
            } catch (ValidateException $e) {
                throw new ApiException(is_string($e->getError()) ? ErrorCode::UNKNOWN_VALIDATE_MSG : $e->getError());
            }
        }

        if (!$this->service->create($data)) {
            return $this->json->api(ErrorCode::CREATE_FAILED);
        }

        return $this->json->api(ErrorCode::SUCCESS);
    }

    /**
     * 修改数据
     *
     * @param int         $id
     * @param string|null $validate
     * @return Response
     */
    public function update(int $id, ?string $validate = null): Response
    {
        $data = $this->request->put();

        if ($validate) {
            try {
                // 验证时传入主键，验证唯一性时排除当前修改的记录
                // 通过判断是否存在主键来决定是新建还是修改
                // 可以直接使用 request 的 param 方法获取全部参数，此处直接传入 $data 即可
                $this->validate(array_merge($data, ['id' => $id]), $validate);
            } catch (ValidateException $e) {
                throw new ApiException(is_string($e->getError()) ? ErrorCode::UNKNOWN_VALIDATE_MSG : $e->getError());
            }
        }

        if (!$this->service->update($id, $data)) {
            return $this->json->api(ErrorCode::UPDATE_FAILED);
        }

        return $this->json->api(ErrorCode::SUCCESS);
    }

    /**
     * 删除数据
     *
     * @param int $id
     * @return Response
     */
    public function delete(int $id): Response
    {
        if (!$this->service->delete($id)) {
            return $this->json->api(ErrorCode::DELETE_FAILED);
        }

        return $this->json->api(ErrorCode::SUCCESS);
    }
}